package com.mew.chess.core.game.qmcs.game;

import com.mew.chess.core.game.qmcs.game.common.QmcsConstantValue;
import com.mew.chess.core.game.qmcs.game.common.QmcsLinkType;
import com.mew.chess.core.game.qmcs.game.task.QmcsPushCycleScheduleTask;
import com.mew.chess.core.game.qmcs.game.task.QmcsScheduleTask;
import com.mew.chess.core.game.qmcs.service.QmcsService;
import com.mew.common.config.SpringContextBean;
import com.mew.common.dc.redis.FishingRedisService;
import com.mew.common.entity.config.FishingQmcs;
import com.zebra.common.concurrent.ZebraExecutorManager;
import com.zebra.common.concurrent.ZebraScheduler;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

@Data
@Slf4j
public class QmcsScheduleManager {

    private AtomicBoolean flag = new AtomicBoolean(false);

    private int roomId;
    private int tableId;

    private ZebraScheduler zebraScheduler;
    private ExecutorService executorService;

    private ScheduledFuture<?>  fishScheduledFuture;
    private ScheduledFuture<?>  fishScheduledFutureCycle;//普通鱼时间轮

    private ScheduledFuture<?>  goldScheduledFuture;//金币持久化

    private QmcsScheduleTask qmcsScheduleTask;
    private QmcsPushCycleScheduleTask qmcsPushCycleScheduleTask;


    private QmcsService qmcsService;


    public QmcsScheduleManager(int tableId, int roomId){

        this.roomId = roomId;
        this.tableId = tableId;

        zebraScheduler = null == zebraScheduler ? ZebraExecutorManager.getInstance().getDefaultScheduler() : zebraScheduler;
        executorService = null == executorService ? ZebraExecutorManager.getInstance().getDefaultExecutor() : executorService;
    }

    public void start(){
        if(flag.compareAndSet(false, true)){
            initializeTask();
            prepareStartTimer();
        }
    }

    public void stop(){
        zebraScheduler.cancelScheduled(fishScheduledFuture);
        zebraScheduler.cancelScheduled(fishScheduledFutureCycle);
        //结算
        qmcsService.payment(roomId,tableId);
        ZebraScheduler.cancelScheduled(goldScheduledFuture);
        flag.getAndSet(false);
        QmcsTableManager table = QmcsGameManager.getInstance().getController(roomId).getTable(tableId);
        table.getQmcsMap().clear();
        table.getFishKeyId().set(1);
        qmcsService.tableLog(table,true);
    }

    private void prepareStartTimer(){
        log.info("---Qmcs Prepare StartTimer：roomId {}", this.getRoomId());
        QmcsTableManager table = QmcsGameManager.getInstance().getController(roomId).getTable(tableId);
        table.setLinkType(QmcsLinkType.Prepare.code());
        table.setStartTime(System.currentTimeMillis());
        table.setRuleTime(QmcsConstantValue.PREPARE_TIME);
        goldScheduledFuture = zebraScheduler.scheduleWithFixedDelay(()->{
            qmcsService.payment(roomId,tableId);}, 600L, QmcsConstantValue.PAYMENT_TIME, TimeUnit.MILLISECONDS, executorService);
        fishScheduledFuture = zebraScheduler.schedule((this::startGame), QmcsConstantValue.PREPARE_TIME, TimeUnit.MILLISECONDS, executorService);
    }

    private void initializeTask(){

        Map<Integer, FishingQmcs> qmcsMap = QmcsGameManager.getInstance().getQmcsMap();
        if (null==qmcsMap||qmcsMap.isEmpty()){
            FishingRedisService fishingRedisService = SpringContextBean.getBean(FishingRedisService.class);
            QmcsGameManager.getInstance().putQmcss(fishingRedisService.findQmcs());
        }

        if (null== qmcsScheduleTask){
            qmcsScheduleTask = SpringContextBean.getBean(QmcsScheduleTask.class);
        }
        if (null== qmcsPushCycleScheduleTask){
            qmcsPushCycleScheduleTask = SpringContextBean.getBean(QmcsPushCycleScheduleTask.class);
        }

        if (null== qmcsService){
            qmcsService = SpringContextBean.getBean(QmcsService.class);
        }
    }

    //-----------start fish-------------------------
    public void startGame(){
        log.info("stopCycle()");
        stopCycle();
        if (!qmcsScheduleTask.fishCycle(roomId,tableId)){
            stop();
            return;
        }

        log.info("---Qmcs start ：roomId {}", this.getRoomId());
        fishScheduledFutureCycle = zebraScheduler.scheduleWithFixedDelay((this::doFishCycle), 600L, QmcsConstantValue.FISH_TIMEER, TimeUnit.MILLISECONDS, executorService);
        fishScheduledFuture = zebraScheduler.schedule((this::startGame), QmcsConstantValue.FISH_TIMEER_CYCLE, TimeUnit.MILLISECONDS, executorService);
    }

    private void doFishCycle(){
        qmcsPushCycleScheduleTask.fishCycle(roomId,tableId,fishScheduledFutureCycle);
    }



    private void stopFishCycle(){
        try {
            zebraScheduler.cancelScheduled(fishScheduledFutureCycle);
        }catch (Exception e){
        }
    }

    private void stopCycle(){
        stopFishCycle();
    }

}
